package com.huanling.main.enums;

import com.huanling.main.keyconflictdealer.*;
import com.huanling.main.keyconflictdealer.ConflictBreakDealer;

import java.util.EnumMap;
import java.util.function.Supplier;

/**
 * @author guibo.sun
 * @since 25 七月 2021
 */
public enum ConflictKeyStrategyEnum {
    /**
     * 严格模式，直接抛错并终止比对
     */
    BREAK,
    /**
     * 如果设置了参照列，则根据参照列判断，相等的两条数据判断为重复数据，仅有重复数据不中断，输出重复数据到日志
     * 若没有设置参照列，则都认为是"相同元素"即重复数据
     */
    IGNORE_DUPLICATE_BREAK,
    /**
     * 默认等级，不会中断
     * 仅使用该key的第一个元素构建hash表，其他相同key的元素忽略，记录冲突和重复数据到日志
     */
    IGNORE,
    /**
     * 宽容模式，不会中断
     * 使用拉链法搜索，通过比较用户选择的"对比列"，尽最大可能找到对应元素（如果没有开启对比，则退化为IGNORE) 并记录日志
     */
    ZIPPER_LOG,
    ;

    /**
     * 根据PECS法则，用于生产数据的泛型类，最好使用extends（ A.get() 属于A生产了一个对象 属于producer ，A.set() 属于消费了一个对象，是consumer)
     */
    private static final EnumMap<ConflictKeyStrategyEnum, Supplier<? extends AbstractConflictKeyDealer>> ROUTER_MAP =
            new EnumMap<>(ConflictKeyStrategyEnum.class);

    static {
        ROUTER_MAP.put(BREAK, ConflictBreakDealer::new);
        ROUTER_MAP.put(IGNORE_DUPLICATE_BREAK, DuplicateIgnoreErrorOutPutDealer::new);
        ROUTER_MAP.put(IGNORE, DefaultConflictKeyDealer::new);
        ROUTER_MAP.put(ZIPPER_LOG, ZipperFindDealer::new);
    }

    public static AbstractConflictKeyDealer getConflictKeyDealer(ConflictKeyStrategyEnum anEnum) {
        Supplier<? extends AbstractConflictKeyDealer> supplier = ROUTER_MAP.get(anEnum);
        return supplier.get();
    }


}
